package com.example.covid19.controller;


import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.covid19.common.Dto.Editdto;
import com.example.covid19.common.lang.Result;
import com.example.covid19.entity.Cheeck;

import com.example.covid19.entity.Student;
import com.example.covid19.entity.mongodb.Location;
import com.example.covid19.mapper.CheeckMapper;
import com.example.covid19.service.CheeckService;
import com.example.covid19.service.StudentService;
import com.example.covid19.util.GraphUtils;
import com.example.covid19.util.MapPoint;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author BaiZhengChun
 * @since 2023-03-07
 */
@RestController
@RequestMapping("/check")
public class CheeckController {
    private final CheeckService cheeckService;
//    private final CheeckService cheeckService;
    private final StudentService studentService;
    private final CheeckMapper cheeckMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private MongoTemplate mongoTemplate;

    public CheeckController(CheeckService cheeckService, StudentService studentService, CheeckMapper cheeckMapper) {
        this.cheeckService = cheeckService;
        this.studentService = studentService;
        this.cheeckMapper = cheeckMapper;
    }

    @RequestMapping("/deletetoken")
    public String deletetoken(){
        redisTemplate.delete("token");
        return "定时任务";
    }
    @RequestMapping("/usually")
    public String usually(){
        String str = "uc.A#?As:QMMom!FnH^2?M+o,Bst!kW:";
        redisTemplate.opsForValue().set("token",str);
                System.out.println();
        return "定时任务";
    }

    /**
     *
     * @param editdto
     * @param httpServletRequest
     * @return 根据前端获取的地址和学生所在宿舍进行判断在不在位置内
     * @throws IOException
     */
    @RequestMapping("/location")
    public boolean location(@RequestBody Editdto editdto,HttpServletRequest httpServletRequest) throws IOException {
        String s = (String) StpUtil.getLoginIdByToken(httpServletRequest.getHeader("satoken"));
        String s1 = cheeckMapper.getlocal(s);
        OkHttpClient client = new OkHttpClient();

        //第二步创建request对象
        okhttp3.RequestBody requestBody = new FormBody.Builder()
                .add("ak","d93mLitYpaZdHYAWEWyoYR9AneSW7ZEx")
                .add("coords",editdto.getFacetoken())
                .build();
        Request request = new Request.Builder()
                .addHeader("content-type", "application/json")
                .url("https://api.map.baidu.com/geoconv/v1/")
                .post(requestBody)
                .build();
        String result = Objects.requireNonNull(client.newCall(request).execute().body()).string();
//        String[] strArr = new String[]{
//                "124.37553,40.18385", "124.37433,40.18520", "124.36995,40.18449", "124.36912,40.18495",
//                "124.36794,40.18415", "124.36740,40.18452", "124.36641,40.18449", "124.36643,40.18384",
//                "124.36679,40.18378", "124.36673,40.18242", "124.36797,40.18179", "124.36897,40.18197",
//                "124.36948,40.18163"
//        };
        String strArr = mongoTemplate.findById(s1, Location.class).getGver();
        List<String> strList = JSONUtil.toList(JSONUtil.parseArray(strArr), String.class);
        List<MapPoint> boundaryPoints = strList.stream().map(v -> {
            String[] arr = v.split(",");
            return new MapPoint(Double.parseDouble(arr[0]), Double.parseDouble(arr[1]));
        }).collect(Collectors.toList());
        JSONObject o  = JSONUtil.parseObj(Objects.requireNonNull(client.newCall(request).execute().body()).string());
        JSONArray jsonArray = (JSONArray) o.get("result");
        double x = (double) jsonArray.getJSONObject(0).get("x");
        double y = (double) jsonArray.getJSONObject(0).get("y");
        return GraphUtils.isPointInPolygon(new MapPoint(x, y), boundaryPoints);
    }

    /**
     *
     * @return检查到没到打卡的时间
     */
    @RequestMapping("checktoken")
    public Result checktoken(){
        if(redisTemplate.opsForValue().get("token")!=null){
            return Result.success(200,"成功",null);
        }else {
            return Result.fail(400,"未到打卡时间",null);
        }
    }
    /**
     * 每天零点清除标识，在调用formatst时将用户没打卡的数据填进打卡表
     */
    public void nocheckin(){
        LocalDate date = LocalDate.now();
        List<Student> studentList = studentService.list(new QueryWrapper<Student>().eq("istrue",0));
        List<Cheeck>cheeckList = new ArrayList<>();
        studentList.forEach(v->{
            Cheeck cheeck = new Cheeck();
            cheeck.setIstrue("0");
            cheeck.setStudentid(v.getStudentid());
            cheeck.setTime(date);
//            cheeck.setQdate(LocalDate.parse("0"));
            cheeckList.add(cheeck);
        });
        cheeckService.saveBatch(cheeckList);
    }

    /**
     * 定时任务清空所有打卡标识
     */
    @RequestMapping("formatst")
    public void formatst(){
        nocheckin();
        List<Student> studentList = studentService.list();
        studentList.forEach(v->{
            v.setIstrue(0);
        });
        System.out.println(studentList);
        studentService.updateBatchById(studentList);
    }

    /**
     *
     * @param httpServletRequest
     * @return 获取当前用户的打卡记录
     */
    @RequestMapping("getmylist")
    public Result getmylist(HttpServletRequest httpServletRequest){
        String s = (String) StpUtil.getLoginIdByToken(httpServletRequest.getHeader("satoken"));
//        List<Cheeck> list = cheeckService.list(new QueryWrapper<Cheeck>().eq("studentid",s)).stream()
//                .peek(v->v.setIstrue())
        if (cheeckService.list(new QueryWrapper<Cheeck>().eq("studentid",s))==null){
            return Result.fail(400,"获取失败",null);
        }else {
            return Result.success(200,"获取成功",cheeckService.list(new QueryWrapper<Cheeck>().eq("studentid",s)));
        }
    }

    /**
     *
     * @param httpServletRequest
     * @return 保存打卡信息
     */
    @RequestMapping("/savecheck")
    public Result savecheck(HttpServletRequest httpServletRequest){
        if(redisTemplate.opsForValue().get("token")!=null){
            String satoken = httpServletRequest.getHeader("satoken");
            System.out.println("satoken="+satoken);
            StpUtil.getLoginIdByToken(satoken);
            LocalTime time = LocalTime.now();
            Cheeck check1 = new Cheeck();
            check1.setIstrue("1");
            check1.setIp("110.2");
            check1.setStudentid(917420002);
            check1.setTtime(time);
            check1.setEnregisterid("fwefwef");
            LocalDate localDate = LocalDate.now();
            check1.setTime(localDate);
            System.out.println(check1);
            boolean flag =  cheeckService.save(check1);
            Student student = studentService.getOne(new QueryWrapper<Student>().eq("studentid",917420002));
            student.setIstrue(1);
            studentService.updateById(student);
            if (flag){
                return Result.success(200,"打卡成功",null);
            }
            else {
                return Result.fail(400,"打卡失败",null);
            }
        }
        else {
            return Result.fail(400,"未到打卡时间！",null);
        }

    }

}